package edu.moravian.entity;

import edu.moravian.CollisionPhysics.EntityCollisionEngine;
import edu.moravian.math.Point2D;
import edu.moravian.math.Vector2D;
import edu.moravian.world.WorldDescriptor;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
/**
 *
 * @author ronaghan
 */
public class BallEntityManager
{

    
    private WorldDescriptor world;
    
    private Random rand;
    
    private List<BallEntity> entities;
    
    private EntityCollisionEngine collisionEngine;
    
    public BallEntityManager(WorldDescriptor world)
    {
                
      this.world = world;

        
        
        rand = new Random();
        
        BallProperties ballProps = new BallProperties();
        
        
        
        collisionEngine = new EntityCollisionEngine(ballProps.getElasticity());

        

        //populate our list of balls from values in the properties file
        entities = new ArrayList<BallEntity>();
        for(int i=0; i<ballProps.getNumBalls(); i++)
        {
            double speed = randInRange(ballProps.getMinSpeed(), ballProps.getMaxSpeed());
            double radius = randInRange(ballProps.getMinRadius(), ballProps.getMaxRadius());
          
            double minX = world.getMinX() + radius;
            double maxX = world.getMaxX() - radius;
            double minY = world.getMinY() + radius;
            double maxY = world.getMaxY() - radius;
            
            Point2D loc = Point2D.randomPoint(minX, maxX, minY, maxY);
            Vector2D heading = Vector2D.randomVectorFixedMagnitude(1.0);
            
                       
            BallEntity ballModel = new BallEntity(loc, heading, speed, radius, radius);
            
            
            entities.add(ballModel);
        }
    }
    
    
    private double randInRange(double low, double high)
    {
        return rand.nextDouble() * (high - low) + low;
    }
    
    
    public int getNumBalls()
    {
        return entities.size();
    }
    
    
    public void increaseEpsilon()
    {
        double elasticity = collisionEngine.getElasticity();
        
        elasticity *= 1.05;
        
        collisionEngine.setElasticity(elasticity);
    }   
    
    public void decreaseEpsilon()
    {
        double elasticity = collisionEngine.getElasticity();
        
        elasticity *= 0.95;
        
        collisionEngine.setElasticity(elasticity);
    }
    
    
    public void update(double delta)
    {
        
        for(BallEntity ball: entities)
        {
            ball.update(delta);
            if(collisionEngine.willCollide(ball, world, delta))
            {
                collisionEngine.collisionResponse(ball, world);
            }
            
        }
        
        
        for(int i=0; i<entities.size()-1; i++)
        {
            for(int j=i+1; j<entities.size(); j++)
            {
                
                BallEntity one = entities.get(i);
                BallEntity two = entities.get(j);
                if(collisionEngine.willCollide(one, two,delta))
                {
                    collisionEngine.collisionResponse(one, two);
                    
                   // entities.get(i).collisionResponse(entities.get(j), epsilon);
                }
            }
        }
    }
    
    
    public Iterable<BallEntity> getBalls()
    {
        return entities;
    }
    
    
   
    
   
    
    
    
}



